﻿using AwesomiumDotNet;
using System;
using System.Drawing;
using System.Windows.Forms;
using SlimDX;
using SlimDX.Direct3D9;

namespace SlimDXSample
{
    class SlimDXSample : Game
    {
        int Width = 1024, Height = 768;
        Color ClearColor = Color.FromArgb(15, 56, 102);
        string URL = "http://www.google.com";

        UIManager ui;
        UIView window1;
        UIInfoForm info;
        Fader fader;

        Mesh box;
        Light light;
        Material material;

        float rotAngle = 0.3f;

        // Shortcut to device
        public SlimDX.Direct3D9.Device Device
        {
            get { return Context9.Device; }
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if (box != null) box.Dispose();
            if (fader != null) fader.Dispose();
            if (ui != null) ui.Dispose();
        }

        protected override void OnInitialize()
        {
            Form.Text = "AwesomiumDotNet sample - SlimDX";
            Form.ClientSize = new Size(Width, Height);

            DeviceSettings9 settings = new DeviceSettings9();
            settings.CreationFlags = CreateFlags.HardwareVertexProcessing;
            settings.Windowed = true;
            InitializeDevice(settings);

            fader = new Fader(Device);

            
            // Create the UI manager and some views
            ui = new UIManager(Device, Form);
            
            info = new UIInfoForm(ui);
            
            window1 = new UIView(ui, 640, 512, UIFlags.Center);
            window1.LoadUrl(URL);


            // DirectX setup: box object, lighting, material
            box = Mesh.CreateBox(Device, 1.0f, 1.0f, 1.0f);
            box.ComputeNormals();

            light = new Light();
            light.Type = LightType.Directional;
            light.Direction = new Vector3(-1, -2, 1);
            light.Diffuse = Color.LemonChiffon;

            material = new Material();
            material.Diffuse = Color.Gray;
            material.Ambient = Color.LawnGreen;
        }

        protected override void OnResourceLoad()
        {
            Device.Material = material;
            Device.SetLight(0, light);
            Device.EnableLight(0, true);
            Device.SetRenderState(RenderState.Ambient, new Color4(0.5f, 0.5f, 0.5f).ToArgb());

            Device.SetRenderState(RenderState.AlphaBlendEnable, true);
            Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
            Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);

            ui.OnResourceLoad();
        }

        protected override void OnResourceUnload()
        {
            ui.OnResourceUnload();
        }

        protected override void OnUpdate()
        {
            ui.WebCore.Update();

            // Handle mouse events
            ui.MouseEvent(Input);

            // Handle keyboard events

            // Exit
            if (Input.KeysDown.Contains(Keys.Escape))
            {
                Quit();
                return;
            }

            // Toggle fullscreen
            if (Input.KeysPressed.Contains(Keys.F11))
                ToggleFullScreen();

            // Toggle transparency
            if (Input.KeysPressed.Contains(Keys.F2))
            {
                info.IsTransparent = !info.IsTransparent;
                window1.IsTransparent = !window1.IsTransparent;
            }

            if (ui.KeyboardEvent(Input) == false)
            {
                // Handle keys that weren't handled by any webviews
            }

            info.SetText(
                "F2 - Toggle transparency</br>" +
                "Esc - Exit</br></br>" +
                "FPS: " + FramesPerSecond.ToString()
            );
        }

        protected override void OnRender()
        {
            Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, ClearColor, 1.0f, 0);
            Device.BeginScene();

            rotAngle += FrameDelta * 0.1f;
            Vector3 cameraPos = new Vector3((float)Math.Sin(rotAngle) * 10, 5, (float)Math.Cos(rotAngle) * 10);

            // Render 3d scene
            
            Matrix Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, (float)Width / (float)Height, 0.1f, 40.0f);
            Matrix View = Matrix.LookAtLH(cameraPos, new Vector3(rotAngle, 0, 10), Vector3.UnitY);
            Device.SetTransform(TransformState.Projection, Projection);
            Device.SetTransform(TransformState.View, View);
            Device.SetTransform(TransformState.World, Matrix.Identity);

            Device.SetRenderState(RenderState.Lighting, true);
            Device.SetRenderState(RenderState.ZEnable, true);

            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    Device.SetTransform(TransformState.World, Matrix.Translation(i*2, 0, j*2));
                    box.DrawSubset(0);
                }
            }

            // Render 2d sprites
            
            Device.SetRenderState(RenderState.Lighting, false);
            Device.SetRenderState(RenderState.ZEnable, false);

            ui.DrawAll();
            fader.Draw(FrameDelta);

            Device.EndScene();
            Device.Present();
        }
    }
}
